﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;

namespace BeachRunner.Utility
{
    /// <summary>
    /// Klasse zum Zugänglichmachen von Touchstati.
    /// 
    /// Autor: Arne Blumentritt, Mathias Müller
    /// </summary>
    public static class IOTouchControl
    {
        private static TouchCollection oldStates;
        private static TouchCollection currentStates = TouchPanel.GetState();

        public static readonly Rectangle RightArea = new Rectangle(Game1.RES_X / 2, 0, Game1.RES_X / 2, Game1.RES_Y);
        public static readonly Rectangle LeftArea = new Rectangle(0, 0, Game1.RES_X / 2, Game1.RES_Y);

        private static bool blockTouch;
        private static double blockTouchTimer;
        public static int BlockTouchTimer
        {
            set { blockTouchTimer = value / Game1.TIME_PER_TICK; }
        }

        private static bool isHorizontalDragRecognized = false;
        /// <summary>
        /// Gibt zurück ob ein HorizontalDrag erkannt wurde
        /// </summary>
        public static bool IsHorizontalDragRecognized
        {
            get { return IOTouchControl.isHorizontalDragRecognized; }
            set { IOTouchControl.isHorizontalDragRecognized = value; }
        }

        private static float horizontalDragDeltaX;
        /// <summary>
        /// Gibt den aktuellen Delta Wert in X Richtung zurück,
        /// Wird gesetzt wenn HorizontalDrag erkannt wurde
        /// </summary>
        public static float HorizontalDragDeltaX
        {
            get { return IOTouchControl.horizontalDragDeltaX; }
        }

        /// <summary>
        /// Speichert die alten Berührungsstati und holt die neuen.
        /// Autor: Arne Blumentritt
        /// </summary>
        public static void Update()
        {
            if (blockTouchTimer > 0)
            {
                blockTouchTimer--;
                blockTouch = true;
            }
            else
                blockTouch = false;

            oldStates = currentStates;
            currentStates = TouchPanel.GetState();
        }

        /// <summary>
        /// Gibt an, ob eine Berührung erfolgt, egal ob sie neu ist.
        /// Autor: Arne Blumentritt
        /// </summary>
        /// <param name="key">Die auszuwertende Taste</param>
        /// <returns>Der Tastenstatus</returns>
        public static bool IsTouchDown()
        {
            foreach (TouchLocation touch in currentStates)
            {
                if ((touch.State == TouchLocationState.Moved || touch.State == TouchLocationState.Pressed) && blockTouch == false)
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// Gibt an, ob eine Berührung in einem Rectangle erfolgt, egal ob sie neu ist.
        /// Autor: Arne Blumentritt
        /// </summary>
        /// <param name="rec">Der Auszuwertende Bereich</param>
        /// <returns>Der Tastenstatus</returns>
        public static bool IsTouchDown(Rectangle rec)
        {
            foreach (TouchLocation touch in currentStates)
            {
                if ((touch.State == TouchLocationState.Moved || touch.State == TouchLocationState.Pressed)
                    && blockTouch == false)
                    if (rec.Contains((int)touch.Position.X, (int)touch.Position.Y))
                        return true;
            }
            return false;
        }

        /// <summary>
        /// Gibt der Touchscreen in einem Rectangle losgelassen wurde.
        /// Autor: Mathias Müller
        /// </summary>
        /// <param name="rec">Der Auszuwertende Bereich</param>
        /// <returns>Der Tastenstatus</returns>
        public static bool IsTouchReleased(Rectangle rec)
        {
            foreach (TouchLocation touch in currentStates)
            {
                if (touch.State == TouchLocationState.Released && blockTouch == false)
                {
                    if (rec.Contains((int)touch.Position.X, (int)touch.Position.Y))
                        return true;
                }
            }
            return false;
        }

        /// <summary>
        /// Gibt der Touchscreen losgelassen wurde.
        /// Autor: Mathias Müller
        /// </summary>
        /// <returns>Der Tastenstatus</returns>
        public static bool IsTouchReleased()
        {
            foreach (TouchLocation touch in currentStates)
            {
                if (touch.State == TouchLocationState.Released && blockTouch == false)
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// Gibt an, ob eine neue Berührung erfolgt.
        /// Autor: Arne Blumentritt
        /// </summary>
        /// <param name="key">Die auszuwertende Taste</param>
        /// <returns>Der Tastenstatus</returns>
        public static bool IsTouchHit()
        {
            foreach (TouchLocation touch in currentStates)
            {
                if ((touch.State == TouchLocationState.Pressed) && blockTouch == false)
                    return true;
            }
            return false;
        }

        /// <summary>
        /// Gibt an, ob eine neue Berührung in einem Rectangle erfolgt.
        /// Autor: Arne Blumentritt
        /// </summary>
        /// <param name="key">Die auszuwertende Taste</param>
        /// <returns>Der Tastenstatus</returns>
        public static bool IsTouchHit(Rectangle rec)
        {
            foreach (TouchLocation touch in currentStates)
            {
                if ((touch.State == TouchLocationState.Pressed) && blockTouch == false)
                {
                    if (rec.Contains((int)touch.Position.X, (int)touch.Position.Y))
                        return true;
                }
            }
            return false;
        }

        /// <summary>
        /// Gibt true zurück wenn eine Horizontale Wischgeste erkannt und beendet wurde.
        /// Wenn nur HorizontalDrag erkannt wurde, wird der DeltaX Wert gesetzt und HorizontalDrag auf true gesetzt, dies ist eine Voraussetzung für HorizontalDragComplete
        /// Author: Mathias Müller
        /// </summary>
        /// <returns>Der Tastenstatus</returns>
        public static bool IsHorizontalDragComplete()
        {
            if (TouchPanel.IsGestureAvailable)
            {
                GestureSample gesture = TouchPanel.ReadGesture();

                if (gesture.GestureType == GestureType.HorizontalDrag)
                {
                    horizontalDragDeltaX = gesture.Delta.X;
                    isHorizontalDragRecognized = true;
                    return true;
                }

                if ((gesture.GestureType == GestureType.DragComplete && isHorizontalDragRecognized) && blockTouch == false)
                {
                    isHorizontalDragRecognized = false;
                    return true;
                }
            }
            return false;
        }
    }
}
